#!/usr/bin/env python3
# -*- coding:utf-8 -*-


"""
error
"""

import enum

@enum.unique
class ErrorLevel(int, enum.Enum):
    """
    错误等级
    """
    NORMAL = 0
    CRITICAL = 1


@enum.unique
class Code(int, enum.Enum):
    """
    错误码
    """
    # success, [0]
    OK = 0
    # rpc errors, intervals[1, 17]

    # http errors, intervals[100, 599]
    BAD_REQUEST = 400
    UNAUTHORIZED = 401
    INTERNAL_SERVER_ERROR = 500

    # common errors, intervals[1000, 9999]
    UNDEFINED_ERROR = 1000
    AGENT_ERROR = 2000

    # business errors, intervals [100000000,999999999]
    # 推荐规则: 固定9位
    #		1~2位为：系统标识位，代表系统编号，范围：[10,99]，例子"10"
    #		3~4位为：模块标识位，代表模块编号，范围：[01,99]，例子"01"
    #		5~6位为：类型标识位，代表功能类型，范围：[01,99]，00:undefined, 01:validation, 02:service, 03:dao, 04:controller,
    #                           		05:mq, 06:rpc, 07:http, 08:task, 09:other
    #		7~9位为：错误标识位，代表具体错误码，范围：[001,999]，例子"001"
    # ErrNoUserID      = New(100102001, "no user id")

    # 业务公共错误码定义（资源、公用的基础校验等）
    # 自行定义


class Error(Exception):
    """
    错误类
    """
    # code information
    code_info = {
        # success
        Code.OK: ("success", ErrorLevel.NORMAL),
        # http errors
        Code.BAD_REQUEST: ("bad request", ErrorLevel.NORMAL),
        Code.UNAUTHORIZED: ("unauthorized", ErrorLevel.NORMAL),
        Code.INTERNAL_SERVER_ERROR: ("internal server error", ErrorLevel.CRITICAL),
        # common errors
        # business errors
        # Code.UNDEFINED_MODEL: ("未定义的模型", ErrorLevel.CRITICAL),
        # Code.INVALID_MODEL: ("无效模型（请查看是否选错模型生成器）", ErrorLevel.CRITICAL),

        # 业务公共错误码定义（资源、公用的基础校验等）
    }

    def __init__(self, code: Code = None, message: str = None, dev_message: str = None):
        self.code = code if code is not None else Code.UNDEFINED_ERROR
        self.message = message if message is not None and message != "" else self.code_info[self.code][0]
        self.dev_message = dev_message if dev_message is not None else ""
        self.level = self.code_info[self.code][1]
        Exception.__init__(self)

    def __str__(self):
        return f"code: {int(self.code)}, message: {self.message}, dev_message: {self.dev_message}, level: {self.level}"

    @classmethod
    def get_message_by_code(cls, code):
        """
        根据错误码获取错误信息
        :param code:
        :return:
        """
        return cls.code_info[code][0]
